home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_068 / mg1b / file.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  11KB  |  406 lines

  1. /*
  2.  *         File commands.
  3.  */
  4. #include    "def.h"
  5.  
  6. BUFFER    *findbuffer();
  7. VOID    makename();
  8. VOID    upmodes();
  9.  
  10. /*
  11.  * insert a file into the current buffer. Real easy - just call the
  12.  * insertfile routine with the file name.
  13.  */
  14. /*ARGSUSED*/
  15. fileinsert(f, n, k) {
  16.     register int    s;
  17.     char        fname[NFILEN];
  18.  
  19.     if ((s=ereply("Insert file: ", fname, NFILEN)) != TRUE)
  20.         return (s);
  21.     adjustcase(fname);
  22.     return (insertfile(fname, (char *) NULL)); /* don't set buffer name */
  23. }
  24.  
  25. /*
  26.  * Select a file for editing.
  27.  * Look around to see if you can find the
  28.  * fine in another buffer; if you can find it
  29.  * just switch to the buffer. If you cannot find
  30.  * the file, create a new buffer, read in the
  31.  * text, and switch to the new buffer.
  32.  */
  33. /*ARGSUSED*/
  34. filevisit(f, n, k) {
  35.     register BUFFER    *bp;
  36.     int        s;
  37.     char        fname[NFILEN];
  38.  
  39.     if ((s=ereply("Find file: ", fname, NFILEN)) != TRUE)
  40.         return (s);
  41.     if ((bp = findbuffer(fname, &s)) == NULL) return s;
  42.     curbp = bp;
  43.     if (showbuffer(bp, curwp, WFHARD) != TRUE) return FALSE;
  44.     if (bp->b_fname[0] == 0)
  45.         return (readin(fname));        /* Read it in.        */
  46.     return TRUE;
  47. }
  48.  
  49. /*
  50.  * Pop to a file in the other window. Same as last function, just
  51.  * popbuf instead of showbuffer.
  52.  */
  53. /*ARGSUSED*/
  54. poptofile(f, n, k) {
  55.     register BUFFER    *bp;
  56.     register WINDOW    *wp;
  57.     int        s;
  58.     char        fname[NFILEN];
  59.  
  60.     if ((s=ereply("Find file in other window: ", fname, NFILEN)) != TRUE)
  61.         return (s);
  62.     if ((bp = findbuffer(fname, &s)) == NULL) return s;
  63.     if ((wp = popbuf(bp)) == NULL) return FALSE;
  64.     curbp = bp;
  65.     curwp = wp;
  66.     if (bp->b_fname[0] == 0)
  67.         return (readin(fname));        /* Read it in.        */
  68.     return TRUE;
  69. }
  70.  
  71. /*
  72.  * given a file name, either find the buffer it uses, or create a new
  73.  * empty buffer to put it in.
  74.  */
  75. BUFFER *
  76. findbuffer(fname, s) char *fname; int *s; {
  77.     register BUFFER    *bp;
  78.     char        bname[NBUFN];
  79.  
  80.     adjustcase(fname);
  81.     for (bp=bheadp; bp!=NULL; bp=bp->b_bufp) {
  82.         if (strcmp(bp->b_fname, fname) == 0) {
  83.             return bp;
  84.         }
  85.     }
  86.     makename(bname, fname);            /* New buffer name.    */
  87.     while ((bp=bfind(bname, FALSE)) != NULL) {
  88.         *s = ereply("Buffer name: ", bname, NBUFN);
  89.         if (*s == ABORT)        /* ^G to just quit    */
  90.             return NULL;
  91.         if (*s == FALSE) {        /* CR to clobber it    */
  92.             bp->b_fname[0] = '\0';
  93.             break;
  94.         }
  95.     }
  96.     if (bp == NULL) bp = bfind(bname, TRUE);
  97.     *s = FALSE;
  98.     return bp;
  99. }
  100.  
  101. /*
  102.  * Read the file "fname" into the current buffer.
  103.  * Make all of the text in the buffer go away, after checking
  104.  * for unsaved changes. This is called by the "read" command, the
  105.  * "visit" command, and the mainline (for "uemacs file").
  106.  */
  107. readin(fname) char *fname; {
  108.     register int        status;
  109.     register WINDOW        *wp;
  110.  
  111.     if (bclear(curbp) != TRUE)        /* Might be old.    */
  112.         return TRUE;
  113.     status = insertfile(fname, fname) ;
  114.     curbp->b_flag &= ~BFCHG;        /* No change.        */
  115.     for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
  116.         if (wp->w_bufp == curbp) {
  117.             wp->w_linep = lforw(curbp->b_linep);
  118.             wp->w_dotp  = lforw(curbp->b_linep);
  119.             wp->w_doto  = 0;
  120.             wp->w_markp = NULL;
  121.             wp->w_marko = 0;
  122.         }
  123.     }
  124.     return status;
  125. }
  126. /*
  127.  * insert a file in the current buffer, after dot. Set mark
  128.  * at the end of the text inserted, point at the beginning.
  129.  * Return a standard status. Print a summary (lines read,
  130.  * error message) out as well. If the
  131.  * BACKUP conditional is set, then this routine also does the read
  132.  * end of backup processing. The BFBAK flag, if set in a buffer,
  133.  * says that a backup should be taken. It is set when a file is
  134.  * read in, but not on a new file (you don't need to make a backup
  135.  * copy of nothing).
  136.  *
  137.  * Warning: Adds a trainling nl to files that don't end in one!
  138.  * Need to fix, but later (I suspect that it will require a change
  139.  * in the fileio files for all systems involved).
  140.  */
  141. insertfile(fname, newname) char fname[], newname[]; {
  142.     register LINE    *lp1;
  143.     register LINE    *lp2;
  144.     LINE        *olp;            /* Line we started at */
  145.     int        opos;            /* and offset into it */
  146.     register WINDOW    *wp;
  147.     register int    i;
  148.     register int    nbytes;
  149.     int        s, nline;
  150.     BUFFER        *bp;
  151.     char        line[NLINE];
  152.  
  153.     bp = curbp;                /* Cheap.        */
  154.     if (newname != (char *) NULL)
  155.         (VOID) strcpy(bp->b_fname, newname);
  156.     if ((s=ffropen(fname)) == FIOERR)     /* Hard file open.    */
  157.         goto out;
  158.     if (s == FIOFNF) {            /* File not found.    */
  159.         if (kbdmop == NULL)
  160.             if (newname != NULL)
  161.                 ewprintf("(New file)");
  162.             else    ewprintf("(File not found)");
  163.         goto out;
  164.     }
  165.     opos = curwp->w_doto;
  166.     /* Open a new line, at point, and start inserting after it */
  167.     (VOID) lnewline();
  168.     olp = lback(curwp->w_dotp);
  169.     nline = 0;            /* Don't count fake line at end */
  170.     while ((s=ffgetline(line, NLINE)) == FIOSUC) {
  171.         nbytes = strlen(line);
  172.         if ((lp1=lalloc((RSIZE) nbytes)) == NULL) {
  173.             s = FIOERR;        /* Keep message on the    */
  174.             break;            /* display.        */
  175.         }
  176.         lp2 = lback(curwp->w_dotp);
  177.         lp2->l_fp = lp1;
  178.         lp1->l_fp = curwp->w_dotp;
  179.         lp1->l_bp = lp2;
  180.         curwp->w_dotp->l_bp = lp1;
  181.         for (i=0; i<nbytes; ++i)
  182.             lputc(lp1, i, line[i]);
  183.         ++nline;
  184.     }
  185.     (VOID) ffclose();            /* Ignore errors.    */
  186.     if (s==FIOEOF && kbdmop==NULL) {    /* Don't zap an error.    */
  187.         if (nline == 1)
  188.             ewprintf("(Read 1 line)");
  189.         else
  190.             ewprintf("(Read %d lines)", nline);
  191.     }
  192.     /* Set mark at the end of the text */
  193.     curwp->w_markp = curwp->w_dotp;
  194.     curwp->w_marko = curwp->w_doto;
  195.     /* Now, delete the results of the lnewline we started with */
  196.     curwp->w_dotp = olp;
  197.     curwp->w_doto = opos;
  198.     (VOID) ldelnewline();
  199.     curwp->w_doto = opos;            /* and dot is right    */
  200. #ifdef    BACKUP
  201.     if (newname != NULL)
  202.         bp->b_flag |= BFCHG | BFBAK;    /* Need a backup.    */
  203.     else    bp->b_flag |= BFCHG;
  204. #else
  205.     bp->b_flag |= BFCHG;
  206. #endif
  207.     /* if the insert was at the end of buffer, set lp1 to the end of
  208.      * buffer line, and lp2 to the beginning of the newly inserted
  209.      * text.  (Otherwise lp2 is set to NULL.)  This is 
  210.      * used below to set pointers in other windows correctly if they
  211.      * are also at the end of buffer.
  212.      */
  213.     lp1 = bp->b_linep;
  214.     if (curwp->w_markp == lp1)
  215.         lp2 = curwp->w_dotp;
  216.     else {
  217. out:        lp2 = NULL;
  218.     }
  219.     for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
  220.         if (wp->w_bufp == curbp) {
  221.             wp->w_flag |= WFMODE|WFEDIT;
  222.             if (wp != curwp && lp2 != NULL) {
  223.                 if (wp->w_dotp == lp1)
  224.                     wp->w_dotp = lp2;
  225.                 if (wp->w_markp == lp1)
  226.                     wp->w_markp = lp2;
  227.                 if (wp->w_linep == lp1)
  228.                     wp->w_linep = lp2;
  229.             }
  230.         }
  231.     }
  232.     if (s == FIOERR)            /* False if error.    */
  233.         return (FALSE);
  234.     return (TRUE);
  235. }
  236.  
  237. /*
  238.  * Take a file name, and from it
  239.  * fabricate a buffer name. This routine knows
  240.  * about the syntax of file names on the target system.
  241.  * BDC1        left scan delimiter.
  242.  * BDC2        optional second left scan delimiter.
  243.  * BDC3        optional right scan delimiter.
  244.  */
  245. VOID
  246. makename(bname, fname) char bname[]; char fname[]; {
  247.     register char    *cp1;
  248.     register char    *cp2;
  249.  
  250.     cp1 = &fname[0];
  251.     while (*cp1 != 0)
  252.         ++cp1;
  253. #ifdef    BDC2
  254.     while (cp1!=&fname[0] && cp1[-1]!=BDC1 && cp1[-1]!=BDC2)
  255.         --cp1;
  256. #else
  257.     while (cp1!=&fname[0] && cp1[-1]!=BDC1)
  258.         --cp1;
  259. #endif
  260.     cp2 = &bname[0];
  261. #ifdef    BDC3
  262.     while (cp2!=&bname[NBUFN-1] && *cp1!=0 && *cp1!=BDC3)
  263.         *cp2++ = *cp1++;
  264. #else
  265.     while (cp2!=&bname[NBUFN-1] && *cp1!=0)
  266.         *cp2++ = *cp1++;
  267. #endif
  268.     *cp2 = 0;
  269. }
  270.  
  271. /*
  272.  * Ask for a file name, and write the
  273.  * contents of the current buffer to that file.
  274.  * Update the remembered file name and clear the
  275.  * buffer changed flag. This handling of file names
  276.  * is different from the earlier versions, and
  277.  * is more compatable with Gosling EMACS than
  278.  * with ITS EMACS.
  279.  */
  280. /*ARGSUSED*/
  281. filewrite(f, n, k) {
  282.     register int    s;
  283.     char        fname[NFILEN];
  284.  
  285.     if ((s=ereply("Write file: ", fname, NFILEN)) != TRUE)
  286.         return (s);
  287.     adjustcase(fname);
  288.     if ((s=writeout(curbp, fname)) == TRUE) {
  289.         (VOID) strcpy(curbp->b_fname, fname);
  290. #ifdef    BACKUP
  291.         curbp->b_flag &= ~(BFBAK | BFCHG);
  292. #else
  293.         curbp->b_flag &= ~BFCHG;
  294. #endif
  295.         upmodes(curbp);
  296.     }
  297.     return (s);
  298. }
  299.  
  300. /*
  301.  * Save the contents of the current buffer back into
  302.  * its associated file. Do nothing if there have been no changes
  303.  * (is this a bug, or a feature). Error if there is no remembered
  304.  * file name. If this is the first write since the read or visit,
  305.  * then a backup copy of the file is made.
  306.  * Allow user to select whether or not to make backup files
  307.  * by looking at the value of makebackup.
  308.  */
  309. #ifdef    BACKUP
  310. static    int    makebackup = 0;
  311. #endif
  312.  
  313. /*ARGSUSED*/
  314. filesave(f, n, k) {
  315.     register int    s;
  316.  
  317.     if ((curbp->b_flag&BFCHG) == 0)    {    /* Return, no changes.    */
  318.         if (kbdmop == NULL) ewprintf("(No changes need to be saved)");
  319.         return (TRUE);
  320.     }
  321.     if (curbp->b_fname[0] == 0) {        /* Must have a name.    */
  322.         ewprintf("No file name");
  323.         return (FALSE);
  324.     }
  325. #ifdef    BACKUP
  326.     if (makebackup && ((curbp->b_flag&BFBAK) != 0)) {
  327.         s = fbackupfile(curbp->b_fname);
  328.         if (s == ABORT)            /* Hard error.        */
  329.             return FALSE;
  330.         if (s == FALSE            /* Softer error.    */
  331.         && (s=eyesno("Backup error, save anyway")) != TRUE)
  332.             return (s);
  333.     }
  334. #endif
  335.     if ((s=writeout(curbp, curbp->b_fname)) == TRUE) {
  336. #ifdef    BACKUP
  337.         curbp->b_flag &= ~(BFCHG | BFBAK);
  338. #else
  339.         curbp->b_flag &= ~BFCHG;
  340. #endif
  341.         upmodes(curbp);
  342.     }
  343.     return (s);
  344. }
  345.  
  346. #ifdef    BACKUP
  347. /* Since we don't have variables (we probably should)
  348.  * this is a command processor for changing the value of
  349.  * the make backup flag.  If no argument is given,
  350.  * sets makebackup to true, so backups are made.  If
  351.  * an argument is given, no backup files are made when
  352.  * saving a new version of a file. Only used when BACKUP
  353.  * is #defined.
  354.  */
  355. /*ARGSUSED*/
  356. makebkfile(f, n, k)
  357. {
  358.     makebackup = !f;    /* make backup if no argument given */
  359.     ewprintf(makebackup ?    "Backup files enabled" :
  360.                 "Disabling backup files");
  361.     return (TRUE);
  362. }
  363. #endif
  364.  
  365. /*
  366.  * This function performs the details of file
  367.  * writing; writing the file in buffer bp to
  368.  * file fn. Uses the file management routines
  369.  * in the "fileio.c" package. Most of the grief
  370.  * is checking of some sort.
  371.  */
  372. writeout(bp, fn) register BUFFER *bp; char *fn; {
  373.     register int    s;
  374.     register LINE    *lp;
  375.  
  376.     if ((s=ffwopen(fn)) != FIOSUC)        /* Open writes message.    */
  377.         return (FALSE);
  378.     lp = lforw(bp->b_linep);        /* First line.        */
  379.     while (lp != bp->b_linep) {
  380.         if ((s=ffputline(&(ltext(lp))[0], llength(lp))) != FIOSUC)
  381.             break;
  382.         lp = lforw(lp);
  383.     }
  384.     if (s == FIOSUC) {            /* No write error.    */
  385.         s = ffclose();
  386.         if (s==FIOSUC && kbdmop==NULL)
  387.             ewprintf("Wrote %s", fn);
  388.     } else                    /* Ignore close error    */
  389.         (VOID) ffclose();        /* if a write error.    */
  390.     if (s != FIOSUC)            /* Some sort of error.    */
  391.         return (FALSE);
  392.     return (TRUE);
  393. }
  394.  
  395. /*
  396.  * Tag all windows for bp (all windows if bp NULL) as needing their
  397.  * mode line updated.
  398.  */
  399. VOID
  400. upmodes(bp) register BUFFER *bp; {
  401.     register WINDOW    *wp;
  402.  
  403.     for (wp = wheadp; wp != NULL; wp = wp->w_wndp)
  404.         if (bp == NULL || curwp->w_bufp == bp) wp->w_flag |= WFMODE;
  405. }
  406.